package static_data

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"

	"gitee.com/nggs/util"
)

func ParseEnumValueAliasString(aliasesString string) (aliases []string) {
	if aliasesString != "" {
		aliases = strings.Split(aliasesString, ";")
	}
	return
}

type EnumValue struct {
	Name        string `xml:",attr"`
	valueString string
	Value       int
	Aliases     []string
	Comment     string `xml:",attr"`
}

func NewEnumValue(name string, valueString string, aliasString string, comment string) (ef *EnumValue) {
	ef = &EnumValue{
		Name:        name,
		valueString: valueString,
		Comment:     comment,
	}
	ef.Aliases = ParseEnumValueAliasString(aliasString)
	return
}

func (v *EnumValue) Format() (err error) {
	v.Name = util.FormatFieldName(v.Name)
	v.Value, err = strconv.Atoi(v.valueString)
	if err != nil {
		return
	}
	if v.Value <= 0 {
		return fmt.Errorf("枚举值必须大于0")
	}
	return
}

type Enum struct {
	Name               string `xml:",attr"`
	Comment            string `xml:",attr"`
	Values             []*EnumValue
	valueStringToValue map[string]*EnumValue
	aliasToValue       map[string]*EnumValue
}

func NewEnum(name string, comment string) (e *Enum) {
	e = &Enum{
		Name:               name,
		Comment:            comment,
		valueStringToValue: map[string]*EnumValue{},
		aliasToValue:       map[string]*EnumValue{},
	}
	return
}

func GetEnumByName(es []*Enum, name string) (e *Enum) {
	for _, E := range es {
		if E.Name == name {
			e = E
			break
		}
	}
	return
}

func (e *Enum) AppendValue(new *EnumValue) (err error) {
	for _, f := range e.Values {
		if f.Name == new.Name {
			return fmt.Errorf("枚举值名[%s]重复", f.Name)
		}
	}
	if len(new.Aliases) > 0 {
		for _, a := range new.Aliases {
			_, ok := e.aliasToValue[a]
			if ok {
				return fmt.Errorf("枚举值[%s]的别名[%s]重复了", new.Name, a)
			}
			e.aliasToValue[a] = new
		}
	}
	e.valueStringToValue[new.valueString] = new
	e.Values = append(e.Values, new)
	return
}

func (e *Enum) Format() (err error) {
	if !strings.HasPrefix(e.Name, "E_") {
		e.Name = "E_" + e.Name
	}
	return
}

func (e Enum) GetValue(aliasOrValueString string) (v *EnumValue) {
	var ok bool
	v, ok = e.aliasToValue[aliasOrValueString]
	if ok {
		return
	}
	for _, V := range e.Values {
		if V.valueString == aliasOrValueString {
			v = V
			break
		}
	}
	return
}

//func (e Enum) GetValueByValueString(valueString string) (v *EnumValue) {
//	for _, V := range e.Values {
//		if V.valueString == valueString {
//			v = V
//			break
//		}
//	}
//	return
//}
//
//func (e Enum) GetValueByAlias(alias string) (v *EnumValue) {
//	v = e.aliasToValue[alias]
//	return
//}

func (e Enum) String() string {
	bs, _ := json.Marshal(e)
	return string(bs)
}
